package cs236369.webserver;


import static org.junit.Assert.*;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.HashMap;
import java.util.Map;

import org.apache.http.Header;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpException;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpRequest;
import org.apache.http.HttpVersion;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.DefaultHttpClientConnection;
import org.apache.http.message.BasicHttpEntityEnclosingRequest;
import org.apache.http.message.BasicHttpRequest;
import org.apache.http.message.BasicRequestLine;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;

import cs236369.webserver.Request;

import cs236369.webserver.ThreadPool;
import cs236369.webserver.WebServer.SocketReaderHandler;;


public class SocketReaderHandlerTest {

	private Request tstRequest;
	private WebServer.RequestHandler tstRequestHandler;
	private	Socket socketClient;
	private	Socket socketServer;
	private ServerSocket serverSocket;
	private Thread listeningThread;
	private WebServer testServer;
	
	
	@Before
	public void init() throws Exception {
		FileInputStream fip = new FileInputStream("configTst.xml");
		testServer = new WebServer(fip);
		serverSocket = new ServerSocket(9999);
		Listner listner = new Listner();
		listeningThread = new Thread(listner); 
		listeningThread.start();
		socketClient = new  Socket(InetAddress.getLocalHost().getHostAddress(), 9999);
	}
	
	class Listner implements Runnable{

		@Override
		public void run() {
			try {
				socketServer = serverSocket.accept();
			} catch (IOException e) {
				e.printStackTrace();
				throw new RuntimeException();
			}
		}
		
	}

	@After
	public void destroy() throws IOException, InterruptedException{
		socketClient.close();
		socketServer.close();
		listeningThread.join();
		serverSocket.close();
	}
	
	
	@Test
	public void testRun() throws IOException, HttpException {
	
		//test for basic response, asking for none existing file
		DefaultHttpClientConnection clientConn = new DefaultHttpClientConnection();
		clientConn.bind(socketClient, new BasicHttpParams());
		HttpRequest httpRequest = new BasicHttpEntityEnclosingRequest(new BasicRequestLine("POST", "/tst.tsp?bla=a", HttpVersion.HTTP_1_1));
		httpRequest.addHeader("host", "127.0.0.1");
		byte[] postParams  = ("bla=a&blabla=b".getBytes());
		
		ByteArrayEntity postbytes = new ByteArrayEntity(postParams);

        httpRequest.addHeader(HttpHeaders.CONTENT_LENGTH, Long.toString(postbytes.getContentLength()));
        httpRequest.addHeader(postbytes.getContentType());
        httpRequest.addHeader(postbytes.getContentEncoding());

		System.out.println("The Request:");
		System.out.println(httpRequest.getParams().getParameter("bla"));
		System.out.println(httpRequest.getRequestLine().getUri());
		System.out.println("/The Request");
		
		/*PrintStream out = new PrintStream(socketClient.getOutputStream());
		for(int i = 0; i < httpRequest.toString().length(); i++)
		{
			out.write(httpRequest.toString().toCharArray()[i]);
		}
		out.flush();
		*/
		
		clientConn.sendRequestHeader(httpRequest);
		((HttpEntityEnclosingRequest)httpRequest).setEntity(postbytes);
		clientConn.sendRequestEntity((HttpEntityEnclosingRequest) httpRequest);
		clientConn.flush();
		clientConn.flush();

		//reading handled page
		while(socketServer == null);
		ThreadPool t = new ThreadPool(1, 1);
		SocketReaderHandler srh = testServer.new SocketReaderHandler(socketServer, t);
		srh.run();
		t.start();
		InputStreamReader in = new InputStreamReader(socketClient.getInputStream());
	      int c;
	      try
	      {
	      while ((c = in.read())!=-1)
	        System.out.print((char)c);
	      }catch (SocketException e){
	    	  if (!e.getMessage().equals("Connection reset"))
	    	  {
	    		  throw e;
	    	  }
	      }
	      
	}

	
	
	@Test
	@Ignore
	public void testRun2() throws IOException, HttpException {
	
		//test for basic response, asking for none existing file
		DefaultHttpClientConnection clientConn = new DefaultHttpClientConnection();
		clientConn.bind(socketClient, new BasicHttpParams());
		HttpRequest httpRequest = new BasicHttpRequest(new BasicRequestLine("GET", "/tst.tsp?bla=a", HttpVersion.HTTP_1_1));
		httpRequest.addHeader("host", "127.0.0.1");
		System.out.println("The Request:");
		System.out.println(httpRequest.getRequestLine().getUri());
		System.out.println("/The Request");
		
		/*PrintStream out = new PrintStream(socketClient.getOutputStream());
		for(int i = 0; i < httpRequest.toString().length(); i++)
		{
			out.write(httpRequest.toString().toCharArray()[i]);
		}
		out.flush();
		*/
		
		clientConn.sendRequestHeader(httpRequest);
		clientConn.flush();

		//reading handled page
		while(socketServer == null);
		ThreadPool t = new ThreadPool(1, 1);
		SocketReaderHandler srh = testServer.new SocketReaderHandler(socketServer, t);
		srh.run();
		t.start();
		InputStreamReader in = new InputStreamReader(socketClient.getInputStream());
	      int c;
	      try
	      {
	      while ((c = in.read())!=-1)
	        System.out.print((char)c);
	      }catch (SocketException e){
	    	  if (!e.getMessage().equals("Connection reset"))
	    	  {
	    		  throw e;
	    	  }
	      }
	      
	}
	
	
}
